import LoaderControlService from "./service";
@Midway.MidwayModule({
    code: "ComponentLoader",
})
class ComponentLoader extends CommonController {

    constructor() {
        super();
        this.metaInfo.name = 'ComponentLoader';
        this.metaInfo.type = ConstVariable.PresenterType.CONTROLLER;
        this.controllers = {};
        this.controllerDepended = {};
        //标记组件是否已经被加载过
        this.hasBeenLoaded = false;
        this.ControlService = new LoaderControlService(this);
    }

    $launch() {
        if (this.Model.Components === undefined) {
            throw Error("can't found property 'Components'");
        }
        this.settings = this.Model.Components;
        //如果从启动器有传递应用域,则将当前的应用域进行记录
        if (this.Model._AppDomain_ !== undefined) {
            this._APP_DOMAIN_ = this.Model._AppDomain_;
        }
        return this._loadAll();
    }

    _loadAll() {
        //先加载页面布局
        var self = this;
        //从model中找设置, 处理如果布局组件不存在model时,也可以正常的require
        var layoutCode = self.settings.layout.presenter !== undefined ?
            self.settings.layout.presenter : self.settings.layout;
        var layoutSelector = self.settings.layout.renderTo != undefined ?
            self.settings.layout.renderTo : null;
        var layoutModel = self.Model[layoutCode];
        //布局组件的z-index从200开始
        self.requireComponent(layoutCode, layoutModel === undefined ? []
                : JSON.parse(layoutModel),
            layoutSelector === null ? null : $(layoutSelector),
            {zindex: 200}).then(function (presenter) {
            presenter._APP_DOMAIN_ = self._APP_DOMAIN_;
            //处理getService返回的两种状态
            presenter.getService().initContainer().done(function () {
                self._loadController();
            });
        });
    }

    _loadController() {
        //加载控制器
        var self = this;
        var ctrlDeffer = [];
        //确认控制器加载顺序
        var loadSequence = this._parseControllerSetting();
        //配置控制器的依赖项目
        this.controllerDepended = this._checkDepended();
        $.each(loadSequence, function (key, value) {
            //控制器也可以有model
            var presenterModel = '';
            var container = null,
                layout = null;
            //控制器也可以被Render到一个特定位置
            if (value.renderTo) {
                container = self.LayoutService.getContainer(value.renderTo);
            } else {
                layout = {
                    left: 0,
                    top: 0,
                    width: 0,
                    height: 0
                };
            }
            if (self.Model[value.presenter]) {
                presenterModel = self.Model[value.presenter];
            }
            var deffer = self.requireComponent(value.presenter, presenterModel === '' ?
                null :
                JSON.parse(presenterModel), container, layout);
            ctrlDeffer.push(deffer);
        });
        return $.when.apply($, ctrlDeffer).done(function () {
            $.each(arguments, function (index, presenter) {
                presenter._APP_DOMAIN_ = self._APP_DOMAIN_;
            });
            //加载组件
            self._loadComponents();
        });
    }

    _loadComponents() {
        var componentDeffer = [];
        var self = this;
        $.each(self.settings.components, function (key, value) {
            var container = self.LayoutService.getContainer(value.renderTo);
            if (container !== null && container.length > 0) {
                //在Model中查找对应Presenter的数据
                var presenterModel = self.Model[value.presenter];
                var deffer = self.requireComponent(value.presenter, presenterModel === undefined ?
                    null :
                    JSON.parse(presenterModel), container);
                componentDeffer.push(deffer);
            }
        });
        return $.when.apply($, componentDeffer).done(function () {
            self.Logger.debug("All Presenter Loaded");
            self.dispatchEvent("PresenterLoaded", ConstVariable.PresenterEventType.IC_PLAYER_EVENT, {});
            $.each(arguments, function (index, presenter) {
                presenter._APP_DOMAIN_ = self._APP_DOMAIN_;
            });
        });
    }

    //处理控制的设置,被依赖的Controller将被优先加载
    _parseControllerSetting() {
        var loadSequence = [];
        for (var i = 0; i < this.settings.controllers.length; i++) {
            this._checkDepend(this.settings.controllers[i], loadSequence, null);
        }
        return loadSequence;
    }

    //构建被依赖列表
    _checkDepended() {
        var depended = {};
        for (var i = 0, len = this.settings.controllers.length; i < len; i++) {
            //如果存在依赖,且依赖数量>0
            if (this.settings.controllers[i].depends && this.settings.controllers[i].depends.length > 0) {
                for (var j = 0, dlen = this.settings.controllers[i].depends.length; j < dlen; j++) {
                    if (depended[this.settings.controllers[i].depends[j].presenter] === undefined) {
                        //设置被依赖对象列表,并将被依赖对象插入
                        depended[this.settings.controllers[i].depends[j].presenter] = [];
                    }
                    depended[this.settings.controllers[i].depends[j].presenter]
                        .push({
                            presenter: this.settings.controllers[i].presenter,
                            property: this.settings.controllers[i].depends[j].property
                        });
                }
            }
        }
        return depended;
    }

    _checkDepend(presenterObj, loadSequence, depended) {
        var index = 0;
        for (var i = 0; i < this.settings.controllers.length; i++) {
            if (this.settings.controllers[i].presenter == presenterObj.presenter) {
                if (this.settings.controllers[i].depends && this.settings.controllers[i].depends.length > 0) {
                    for (var j = 0; j < this.settings.controllers[i].depends.length; j++) {
                        //避免自依赖
                        if (this.settings.controllers[i].depends[j].presenter == presenterObj.presenter) {
                            continue;
                        }
                        if (depended) {
                            //避免循环依赖
                            if (this.settings.controllers[i].depends[j].presenter == depended.presenter) {
                                continue;
                            }
                        }
                        this._checkDepend(this.settings.controllers[i].depends[j], loadSequence, this.settings.controllers[i]);
                    }
                } else {
                    index = _.findIndex(loadSequence, function (o) {
                        return o.presenter == presenterObj.presenter;
                    });
                    //不存在
                    if (index == -1) {
                        loadSequence.push(presenterObj);
                    }
                }
            }
        }
        index = loadSequence.findIndex(function (o) {
            return o.presenter == presenterObj.presenter;
        });
        //不存在
        if (index == -1) {
            loadSequence.push(presenterObj);
        }
    }
}